home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Tools / idle / ClassBrowser.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  5.0 KB  |  169 lines

  1. """Primitive class browser.
  2.  
  3. XXX TO DO:
  4.  
  5. - reparse when source changed
  6. - add popup menu with more options (e.g. doc strings, base classes, imports)
  7. - show function argument list (have to do pattern matching on source)
  8. - should the classes and methods lists also be in the module's menu bar?
  9.  
  10. """
  11.  
  12. import os
  13. import string
  14. import pyclbr
  15. from Tkinter import *
  16. import tkMessageBox
  17. from WindowList import ListedToplevel
  18. from Separator import HSeparator
  19.  
  20. from ScrolledList import ScrolledList
  21.  
  22.  
  23. class ClassBrowser:
  24.  
  25.     def __init__(self, flist, name, path=[]):
  26.         root = flist.root
  27.         try:
  28.             dict = pyclbr.readmodule(name, path)
  29.         except ImportError, msg:
  30.             tkMessageBox.showerror("Import error", str(msg), parent=root)
  31.             return
  32.         if not dict:
  33.             tkMessageBox.showerror("Nothing to browse",
  34.                 "Module %s defines no classes" % name, parent=root)
  35.             return
  36.         self.flist = flist
  37.         self.dict = dict
  38.         self.root = root
  39.         self.top = top = ListedToplevel(root)
  40.         self.top.protocol("WM_DELETE_WINDOW", self.close)
  41.         self.top.bind("<Escape>", self.close)
  42.         top.wm_title("Class Browser - " + name)
  43.         top.wm_iconname("ClBrowser")
  44.         self.sepa = HSeparator(top)
  45.         leftframe, rightframe = self.sepa.parts()
  46.         self.leftframe = leftframe
  47.         self.rightframe = rightframe
  48.         leftframe.pack(side="left", fill="both", expand=1)
  49.         # Create help label
  50.         self.helplabel = Label(leftframe, text="Module %s" % name,
  51.                                relief="groove", borderwidth=2)
  52.         self.helplabel.pack(fill="x")
  53.         # Create top frame, with scrollbar and listbox
  54.         self.classviewer = ClassViewer(
  55.             self.leftframe, self.flist, self)
  56.         # Load the classes
  57.         self.load_classes(dict, name)
  58.  
  59.     def close(self, event=None):
  60.         self.classviewer = None
  61.         self.methodviewer = None
  62.         self.top.destroy()
  63.  
  64.     def load_classes(self, dict, module):
  65.         self.classviewer.load_classes(dict, module)
  66.         if self.methodframe:
  67.             self.methodframe.destroy()
  68.             self.methodframe = None
  69.         self.methodviewer = None
  70.  
  71.     methodframe = None
  72.     methodhelplabel = None
  73.     methodviewer = None
  74.  
  75.     def show_methods(self, cl):
  76.         if not self.methodframe:
  77.             self.methodframe = Frame(self.rightframe)
  78.             self.methodframe.pack(side="right", expand=1, fill="both")
  79.             self.methodhelplabel = Label(self.methodframe,
  80.                                relief="groove", borderwidth=2)
  81.             self.methodhelplabel.pack(fill="x")
  82.             self.methodviewer = MethodViewer(self.methodframe, self.flist)
  83.         self.methodhelplabel.config(text="Class %s" % cl.name)
  84.         self.methodviewer.load_methods(cl)
  85.  
  86.  
  87. class ClassViewer(ScrolledList):
  88.  
  89.     def __init__(self, master, flist, browser):
  90.         ScrolledList.__init__(self, master, width=40)
  91.         self.flist = flist
  92.         self.browser = browser
  93.  
  94.     def load_classes(self, dict, module):
  95.         self.clear()
  96.         self.dict = dict
  97.         items = []
  98.         for key, value in dict.items():
  99.             if value.module == module:
  100.                 items.append((value.lineno, key, value))
  101.         items.sort()
  102.         for lineno, key, value in items:
  103.             s = key
  104.             if value.super:
  105.                 super = []
  106.                 for sup in value.super:
  107.                     name = sup.name
  108.                     if sup.module != value.module:
  109.                         name = "%s.%s" % (sup.module, name)
  110.                     super.append(name)
  111.                 s = s + "(%s)" % string.join(super, ", ")
  112.             self.append(s)
  113.  
  114.     def getname(self, index):
  115.         name = self.listbox.get(index)
  116.         i = string.find(name, '(')
  117.         if i >= 0:
  118.             name = name[:i]
  119.         return name
  120.  
  121.     def getclass(self, index):
  122.         return self.dict[self.getname(index)]
  123.  
  124.     def on_select(self, index):
  125.         self.show_methods(index)
  126.  
  127.     def on_double(self, index):
  128.         self.show_source(index)
  129.  
  130.     def show_methods(self, index):
  131.         cl = self.getclass(index)
  132.         self.browser.show_methods(cl)
  133.  
  134.     def show_source(self, index):
  135.         cl = self.getclass(index)
  136.         if os.path.isfile(cl.file):
  137.             edit = self.flist.open(cl.file)
  138.             edit.gotoline(cl.lineno)
  139.  
  140.  
  141. class MethodViewer(ScrolledList):
  142.  
  143.     def __init__(self, master, flist):
  144.         ScrolledList.__init__(self, master)
  145.         self.flist = flist
  146.  
  147.     classinfo = None
  148.  
  149.     def load_methods(self, cl):
  150.         self.classinfo = cl
  151.         self.clear()
  152.         items = []
  153.         for name, lineno in cl.methods.items():
  154.             items.append((lineno, name))
  155.         items.sort()
  156.         for item, name in items:
  157.             self.append(name)
  158.  
  159.     def click_event(self, event):
  160.         pass
  161.  
  162.     def on_double(self, index):
  163.         self.show_source(self.get(index))
  164.  
  165.     def show_source(self, name):
  166.         if os.path.isfile(self.classinfo.file):
  167.             edit = self.flist.open(self.classinfo.file)
  168.             edit.gotoline(self.classinfo.methods[name])
  169.